"""它是一个提供成员相关功能的模块."""
import math
from datetime import date, datetime, timedelta
from typing import Tuple, Union

from fastapi import Request

from core.models import Board, Config, Group, Member


class MemberDetails:
    mb_no: int = 0
    mb_id: str = None
    mb_name: str = None
    mb_nick: str = None
    mb_email: str = None
    mb_homepage: str = None
    mb_level: int = 1
    mb_tel: str = None
    mb_hp: str = None
    mb_certify: str = None
    mb_adult: int = 0
    mb_signature: str = None
    mb_point: int = 0
    mb_today_login: datetime = None
    mb_login_ip: str = None
    mb_datetime: datetime = None
    mb_ip: str = None
    mb_leave_date: str = None
    mb_intercept_date: str = None
    mb_mailling: int = 0
    mb_sms: int = 0
    mb_profile: int = 0

    _admin_type: str = None

    def __init__(
        self,
        request: Request,
        member: Member,
        board: Board = None,
        group: Group = None
    ):
        # TODO: 反复调用的问题必须解决.
        # print("__init__", member)
        super().__init__()

        self.request = request
        self.config = request.state.config
        # member的属性 class 复制到属性
        if member:
            for key, value in member.__dict__.items():
                setattr(self, key, value)
        self.level: int = self.mb_level
        self.admin_type: Union[str, None] = self.get_admin_type(group, board)

    def get_admin_type(self, group: Group = None, board: Board = None) -> Union[str, None]:
        """“确认是否为公告栏管理员后，返回管理员类型
            Args:
            group（Group，optional）：关于公告栏组。Defaults to None.
            board（Board，optional）：公告栏信息。Defaults to None.

            Returns:
            Union[str，None]：管理员类型（super，group，board，None）

        """
        if not self.mb_id:
            return None

        group = group or (board.group if board else None)

        is_authority = None
        if self.config.cf_admin == self.mb_id:
            is_authority = "super"
        elif group and group.gr_admin == self.mb_id:
            is_authority = "group"
        elif board and board.bo_admin == self.mb_id:
            is_authority = "board"

        return is_authority

    def is_super_admin(self) -> bool:
        """检查高层管理人员是否"""
        cf_admin = str(self.config.cf_admin).lower().strip()

        if not cf_admin:
            return False

        if self.mb_id and self.mb_id.lower().strip() == cf_admin:
            return True

        return False


def get_member_level(request: Request) -> int:
    """request函数从获取成员级信息"""
    member: Member = request.state.login_member

    return int(member.mb_level) if member else 1


def get_admin_type(request: Request, mb_id: str = None,
                   group: Group = None, board: Board = None) -> Union[str, None]:
    """检查公告板管理员后，经理类型返回
    - nouboard5的 is_admin 我试图参考一个函数来写它。, 已经 is_admin我必须更改函数名称

    Args:
        request (Request): FastAPI Request 对象
        mb_id (str, optional): 会员Id. Defaults to None.
        group (Group, optional): 公告组信息. Defaults to None.
        board (Board, optional): 公告板信息. Defaults to None.

    Returns:
        Union[str, None]: 经理类型 (super, group, board, None)
    """
    if not mb_id:
        return None

    config = request.state.config
    group = group or (board.group if board else None)

    is_authority = None
    if config.cf_admin == mb_id:
        is_authority = "super"
    elif group and group.gr_admin == mb_id:
        is_authority = "group"
    elif board and board.bo_admin == mb_id:
        is_authority = "board"

    return is_authority


def is_super_admin(request: Request, mb_id: str = None) -> bool:
    """检查高层管理人员是否

    Args:
        request (Request): FastAPI Request 对象
        mb_id (str, optional): 会员Id. Defaults to None.

    Returns:
        bool: 如果你是高级经理， True, 或者也许 False
    """
    config: Config = request.state.config
    cf_admin = str(config.cf_admin).lower().strip()

    if not cf_admin:
        return False

    mb_id = mb_id or request.session.get("ss_mb_id", "")
    if mb_id and mb_id.lower().strip() == cf_admin:
        return True

    return False


def get_next_open_date(request: Request, open_date: date = None) -> str:
    """可以释放下一个配置文件。

    Args:
        request (Request): FastAPI Request 对象
        open_date (date): 最近的配置文件公共更改

    Returns:
        datetime: 可能的下一个配置文件发布
    """
    open_days = getattr(request.state.config, "cf_open_modify", 0)
    if open_days == 0:
        return ""

    base_date = open_date if open_date else date.today()
    calculated_date = base_date + timedelta(days=open_days)

    return calculated_date.strftime("%Y-%m-%d")


def hide_member_id(mb_id: str):
    """函数来使用这个想法
    - 想法的一半, 隐藏的部分 *标记为.

    Args:
        mb_id (str): 会员Id

    Returns:
        str: 隐藏成员的名称
    """
    id_len = len(mb_id)
    hide_len = math.floor(id_len / 2)
    start_len = math.ceil((id_len - hide_len) / 2)
    end_len = math.floor((id_len - hide_len) / 2)
    return mb_id[:start_len] + "*" * hide_len + mb_id[-end_len:]


def set_zip_code(zip_code: str = None) -> Tuple[str, str]:
    """来回你的邮政号码 3除以一个地方的函数

    Args:
        zip_code (str): 邮政号码

    Returns:
        Tuple[str, str]: (前 3的地方, 背面 3的地方)
    """
    if not zip_code:
        return "", ""

    return zip_code[:3], zip_code[3:6]
